package c6;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;

/**
 * 自定义Collector
 */
public class ToListCollector<T> implements Collector<T, List<T>,List<T>> {

    /**
     * 建立新的结果容器(Supplier:供应者)
     */
    @Override
    public Supplier<List<T>> supplier() {
        return ArrayList::new;
    }

    /**
     * 将元素添加到结果容器
     */
    @Override
    public BiConsumer<List<T>, T> accumulator() {
        return List::add;
    }

    /**
     * combiner:组合器，合并两个结果容器
     */
    @Override
    public BinaryOperator<List<T>> combiner() {
        return (list1,list2)->{
            list1.addAll(list2);
            return list1;
        };
    }

    /**
     * 对结果容器应用最终转换
     *
     */
    @Override
    public Function<List<T>, List<T>> finisher() {
        return Function.identity();
    }

    /**
     * 定义了收集器的行为，尤其是流是否可以并行归约，characteristics：特性
     * Characteristics是一个包含三个项目的枚举。
     *  UNORDERED——归约结果不受流中项目的遍历和累积顺序的影响。
     *  CONCURRENT——accumulator函数可以从多个线程同时调用，且该收集器可以并行归
     * 约流。如果收集器没有标为UNORDERED，那它仅在用于无序数据源时才可以并行归约。
     *  IDENTITY_FINISH——这表明完成器方法返回的函数是一个恒等函数，可以跳过。这种
     * 情况下，累加器对象将会直接用作归约过程的最终结果。这也意味着，将累加器A不加检查地转换为结果R是安全的。
     */
    @Override
    public Set<Characteristics> characteristics() {
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH,Characteristics.CONCURRENT));
    }
}
